package zdh.fsy.jjwcVehicle.rxx.sendmsg;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class SendPathCmd
    implements SendCmd {
  private PathCmdData data;

  public SendPathCmd(PathCmdData data) {
    this.data = data;
  }

  /**
   * if return null that mean exception occurrence;
   *
   * @return json format message or null
   */
  @Override
  public String getSendCmdMsg() {

//    return createCmdMsgByString();
    return createCmdMsgByJsonUtils();
  }

  @Override
  public String getRequestPath() {
    return "/rbrainrobot/set_robot_fix_path";
  }

  private String createCmdMsgByJsonUtils() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    ObjectNode objectNode = mapper.createObjectNode();
    String result = null;
    try {
      objectNode.set("data", mapper.valueToTree(data));
      result = mapper.writeValueAsString(objectNode);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }

  private String createCmdMsgByString() {
    return "{" + "\"data\":{" + "\"mapcode\":" + "\"" + data.getMapcode() + "\"," + "\"robot_paths\":[{" + "\"start_node\":" + "\"" + data.getRobot_paths().get(0).getStart_node() + "\"," + "\"goal_node\":" + "\"" + data.getRobot_paths().get(0).getGoal_node() + "\"," + "\"index\":" + data.getRobot_paths().get(0).getIndex() + "," + "\"robot_first_path\":" + data.getRobot_paths().get(0).robot_first_path + "," + "\"follow_control\":false" + "}]" + "}" + "}";

  }

  @Data
  public static class PathCmdData {
    private String mapcode;
    private List<RXXPath> robot_paths;

    public PathCmdData(String mapcode, String start_node, String goal_node, Integer stepIndex,
                       Boolean isInPath) {
      this.mapcode = mapcode;
      this.robot_paths = List.of(new RXXPath(start_node, goal_node, stepIndex, isInPath));
    }

    /**
     * 创建对应的路径指令，没有的元素可以直接设置为null
     * @param mapcode：地图的名字
     * @param start_node：开始的节点名字
     * @param goal_node：结束的节点名字
     * @param stepIndex：指令的id
     * @param path_speed：行进的agv速度
     * @param isInPath：如果作为第一个指令，那么需要告知agv是否是在路径之间
     * @param reverse：是否进行直行，false：倒退，ture表示直行，默认直行
     */
    public PathCmdData(String mapcode, String start_node, String goal_node, Integer stepIndex,
                       Integer path_speed, Boolean isInPath, Boolean reverse) {
      this.mapcode = mapcode;
      this.robot_paths = List.of(new RXXPath(start_node, goal_node, null, stepIndex, path_speed, isInPath, reverse, null));
    }
  }

  @Data
  public static class RXXPath {
    private String start_node;
    private String goal_node;
    /**
     * 是否启动 托盘随动控制
     */
    private Boolean follow_control;
    /**
     * 路径所处的step id
     */
    private Integer index;
    private Integer path_speed;
    private Boolean robot_first_path;
    private Boolean reverse;
    private PathAction action;

    public RXXPath(String start_node, String goal_node, Integer stepIndex, boolean isInPath) {
      this.start_node = start_node;
      this.goal_node = goal_node;
      this.index = stepIndex;
      this.robot_first_path = isInPath;
    }


    public RXXPath(String start_node, String goal_node, Integer stepIndex, Integer path_speed,
                   boolean isInPath) {
      this(start_node, goal_node, stepIndex, isInPath);
      this.path_speed = path_speed;
    }

    public RXXPath(String start_node, String goal_node, Boolean follow_control, Integer index, Integer path_speed, Boolean isInPath, Boolean reverse, PathAction action) {
      this(start_node, goal_node, index, isInPath);
      if (follow_control != null) {
        this.follow_control = follow_control;
      }
      if (path_speed != null) {
        this.path_speed = path_speed;
      }
      if (reverse != null) {
        this.reverse = reverse;
      }
      if (action != null) {
        this.action = action;
      }
    }

    @Data
    public static class PathAction {
      private Integer action_type;
      private Float action_height;
      private Integer action;
      private Integer qr_code_id;
      private Boolean immediate_status;
    }

  }

  public static void main(String[] args) {
    PathCmdData pathCmdData = new PathCmdData("123", "1", "2", 1, false);
    SendPathCmd sendPathCmd = new SendPathCmd(pathCmdData);
    System.out.println(sendPathCmd.getSendCmdMsg());

  }
}


